
# База автомобилей
Есть большой файл с данными об автомобилях в формате JSON вида:

``` json
...
{
	"kmage": 0,
	"model": "VW Tiguan",
	"generation": "Volkswagen Tiguan II Рестайлинг",
	"price": 2003400,
	"year": 2021,
	"transmission": "робот",
	"body": "внедорожник 5 дв.",
	"drive": "передний",
	"color": "Status Plus",
	"volume": 1.4,
	"power": 150,
	"fuel": "Бензин"
},
...
```
а) Превратить файл в обычный словарь, из словаря достать список машин по ключу "data" 
https://docs.python.org/3/library/json.html#json.load
``` python
f = open(...)
d = json.load(f)
# ...
```

б) Создать класс Car, который содержит информацию о товаре
все ключи превратить в атрибуты (можно для начала название, цену, год, пробег)

в) Сделать так, чтобы у машины можно было спрашивать, удовлетворяет ли она тому, что хочет пользователь. 

Можно писать произвольный набор параметров, не обязательно все.
``` python
Car.match({'model': 'Ford Focus', 'year': 2010, 'transmission': 'автомат'})
Car.match({'model': 'Ford Focus', 'fuel': 'Бензин', 'transmission': 'автомат'})
```

г) Добавить возможность передавать в словаре с запросом не только точные значения, но и кортежи. Кортеж будет означать диапазон (начало, конец). Если одна из границ диапазона не указана, то она будет None:
``` python
Car.match({'model': 'Ford Focus', 'year': (2000, 2010), 'price': (0, 500000)})
Car.match({'model': 'Ford Focus', 'year': (None, 2010), 'price': (100000, None)})
```

д) Добавить возможность передавать в том же словаре список или множество - набор вариантов.
``` python
Car.match({'model': ['Ford Focus', 'Renault Logan']})
Car.match({'model': {'Ford Focus', 'Renault Logan'}})  # то же самое
Car.match({'model': {'Ford Focus', 'Renault Logan'}, 'transmission': {'механика', 'вариатор', 'автомат'}})
```

е) Сделать класс Selection - выборка. Список авто, которому можно передавать фильтр, и он вернёт новую выброку.
``` python
db = Selection(.....)
sel = db.filter({'model': 'Ford Focus', 'year': (2000, 2010)})  # вернётся тоже Selection
```

ж) (по желанию) Сделать метод filters через \*\*kwargs, то есть, переёти от одного аргумента-словаря к множеству именованных аргументов.

``` python
# было
sel = db.filter({'model': 'Ford Focus', 'year': (2000, 2010)})  # вернётся тоже Selection

# стало
sel = db.filter(model='Ford Focus', year=(2000, 2010))
```

з) В класс Selection добавить метод sort() - сортировка по указанному полю. Результат операции - новая выборка Selection.
``` python
sel2 = sel.sort('year')
sel2 = sel.sort(by='year')  # можно сделать с именем аргумента
sel2 = sel.sort(by='year', ascending=False)  # опционально - в порядке убывания
```

и) (по желанию) Сделать многоуровневую сортировку
``` python
sel3 = sel.sort(by=('year', 'price'))  # авто с одинаковым годом сортируются по возрастанию цены
```

й) В классе Selection сделать метод get_unique() - множество уникальных значений этой выборки по указанному полю
``` python
transmissions = db.get_unique('transmission') # множество set типов коробки передач (str) в базе данных
models = sel1.get_unique('model') # множество set названий моделей str в выборке sel1
```

к) В классе Selection сделать метод get_column() - список значений указанного поля в выборке. Порядок элементов в списке - тот же, что и у элементов исходной выборки.
``` python
price_col = cars5.get_column('price') # список list
```

\* л) В классе Selection сделать метод group_by() - сводка по указанной колонке. См. пример ниже. Результат операции - таблица в виде словаря dict словарей dict.
``` python
agg1 = cars1.group_by('model', {'price_avg': ('price', mean), 'price_max': ('price', max), 'kmage_min': ('kmage', min)})
agg2 = cars1.group_by('transmission', {'price_avg': ('price', mean), 'price_max': ('price', max), 'price_min': ('price', min)})
```
